package com.senlingspace.payment.douyin.service.impl;

import com.alibaba.fastjson2.JSON;
import com.senlingspace.common.core.domain.AjaxResult;
import com.senlingspace.common.enums.GoodsStatusEnum;
import com.senlingspace.common.enums.LakalaTradeStateEnum;
import com.senlingspace.common.enums.OrderBusinessStatus;
import com.senlingspace.common.enums.OrderType;
import com.senlingspace.common.exception.ServiceException;
import com.senlingspace.common.utils.AesUtil;
import com.senlingspace.common.utils.DateUtils;
import com.senlingspace.common.utils.SecurityUtils;
import com.senlingspace.common.utils.StringUtils;
import com.senlingspace.common.utils.http.HttpUtils;
import com.senlingspace.payment.douyin.DouyinHttpClient;
import com.senlingspace.payment.douyin.bean.request.DouyinOrderRequest;
import com.senlingspace.payment.douyin.bean.request.DouyinPreVerifyTicketRequest;
import com.senlingspace.payment.douyin.bean.request.DouyinShopQueryRequest;
import com.senlingspace.payment.douyin.bean.request.DouyinVerifyTicketRequest;
import com.senlingspace.payment.douyin.bean.response.DouyinPreVerifyTicketResponse;
import com.senlingspace.payment.douyin.bean.response.DouyinShopQueryResponse;
import com.senlingspace.payment.douyin.bean.response.DouyinVerifyTicketResponse;
import com.senlingspace.payment.douyin.service.DouYinOrderService;
import com.senlingspace.payment.douyin.service.DouYinShopService;
import com.senlingspace.payment.douyin.service.DouYinTicketService;
import com.senlingspace.system.domain.SlkjOrder;
import com.senlingspace.system.domain.SlkjOrderStatusLog;
import com.senlingspace.system.domain.SlkjShop;
import com.senlingspace.system.mapper.SlkjOrderMapper;
import com.senlingspace.system.mapper.SlkjOrderStatusLogMapper;
import com.senlingspace.system.service.ISlkjOrderService;
import com.senlingspace.system.service.ISlkjShopService;
import jodd.util.StringUtil;
import jodd.util.ThreadUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


@Service
@Slf4j
public class DouYinTicketServiceImpl implements DouYinTicketService {


    @Autowired
    ISlkjShopService slkjShopService;
    @Autowired
    DouYinShopService douYinShopService;
    @Autowired
    DouYinOrderService douYinOrderService;
    @Autowired
    ISlkjOrderService iSlkjOrderService;
    @Autowired
    private SlkjOrderMapper slkjOrderMapper;
    @Autowired
    private SlkjOrderStatusLogMapper slkjOrderStatusLogMapper;

//    @Override
//    public AjaxResult DiffQrcode(String qrcode) {

//        if (StringUtils.isBlank(qrcode)) {
//            log.info("二维码为空！");
//            return AjaxResult.error("二维码有误！");
//        }
//        // 格式为：shop_id#verify_code#order_id
//        String content = AesUtil.decryptQrcode(qrcode);
//
//        if (StringUtils.isBlank(content) || !content.contains("#") || content.split("#").length != 3) {
//            if (content.contains("https://v.douyin.com")) {
//
//                //            抖音券核销
//                DouyinVerifyTicketResponse douyinVerifyTicketResponse = prepare(content, shopId);
//
//                SlkjOrder order = slkjOrderMapper.selectSlkjOrderByOrderId(orderId);
//                if (order == null) {
//                    return AjaxResult.error("订单不存在！");
//                }
//                return AjaxResult.success("核销成功！", order.getOrderId());
//
//            } else {
//                log.info("二维码格式有误，假冒二维码！");
//                return AjaxResult.error("二维码有误！");
//            }
//        }
//        return iSlkjOrderService.validateQrcode(qrcode);
//

//    }


    @Override
    public AjaxResult prepare(String douyinShortUrl, Long shopId) {
        log.info("扫描获取短链接： " + douyinShortUrl);
        DouyinVerifyTicketResponse douyinVerifyTicketResponse = null;
        try {

            String longUrl = getRedirectedUrl(douyinShortUrl);
            String encryptedData = extractObjectId(longUrl);
            if (encryptedData == null) {
                log.error(" 获取不到object_id参数。请求到的长链接如下 ：" + longUrl + "\n");
                throw new ServiceException(" 获取不到object_id参数。请求到的长链接如下 ：" + longUrl + "\n");
            }

            // 对提取的 encrypted_data 进行 URL 编码，编码格式为 UTF-8
            String encodedEncryptedData = URLEncoder.encode(encryptedData, StandardCharsets.UTF_8.toString());
            log.info("URL 编码后的 encrypted_data 参数值：" + encodedEncryptedData);
            log.info("encrypted_data 参数值：" + encryptedData);

            DouyinPreVerifyTicketRequest douyinPreVerifyTicketRequest = new DouyinPreVerifyTicketRequest();
            douyinPreVerifyTicketRequest.setEncryptedData(encodedEncryptedData);
            //       获取商店详细数据
            SlkjShop slkjShop = slkjShopService.selectSlkjShopByShopId(shopId);
            //      获取抖音门店信息
            DouyinShopQueryRequest douyinShopQueryRequest = new DouyinShopQueryRequest();
            douyinShopQueryRequest.setAccountId(slkjShop.getAccountId());
            DouyinShopQueryResponse douyinShopQueryResponse = douYinShopService.prepare(douyinShopQueryRequest);

            if (douyinShopQueryResponse.getExtra().getErrorCode() != 0) {
                log.error("获取抖音门店信息异常: {}", JSON.toJSONString(douyinShopQueryRequest));
                throw new ServiceException(String.format("获取抖音门店信息异常: %s", JSON.toJSONString(douyinShopQueryRequest)));
            }
            //      抖音门店ID
            String poiId = douyinShopQueryResponse.getData().getPois().get(0).getPoi().getPoiId();

            douyinPreVerifyTicketRequest.setPoiId(poiId);
            log.info("验券准备请求参数：" + JSON.toJSONString(douyinPreVerifyTicketRequest));
            //验券准备
            DouyinPreVerifyTicketResponse douyinPreVerifyTicketResponse = DouyinHttpClient.invoke(douyinPreVerifyTicketRequest);
            if (douyinPreVerifyTicketResponse != null && douyinPreVerifyTicketResponse.getData().getErrorCode() == 0L) {
                log.info("验券前置条件满足，开始验券：{}", JSON.toJSONString(douyinPreVerifyTicketResponse) );
                String orderId = douyinPreVerifyTicketResponse.getData().getOrderId();

                DouyinVerifyTicketRequest douyinVerifyTicketRequest = new DouyinVerifyTicketRequest();
                String verifyToken = douyinPreVerifyTicketResponse.getData().getVerifyToken();
                douyinVerifyTicketRequest.setVerifyToken(verifyToken);
                douyinVerifyTicketRequest.setPoiId(douyinPreVerifyTicketRequest.getPoiId());
                List<DouyinPreVerifyTicketResponse.Certificate> certificates = douyinPreVerifyTicketResponse.getData().getCertificates();
                for (DouyinPreVerifyTicketResponse.Certificate certificate : certificates) {
                    douyinVerifyTicketRequest.getEncryptedCodes().add(certificate.getEncryptedCode());
                }
                log.info("验券请求参数：" + JSON.toJSONString(douyinVerifyTicketRequest));
                douyinVerifyTicketResponse = DouyinHttpClient.invoke(douyinVerifyTicketRequest);
                log. info("验券响应参数：" + JSON.toJSONString(douyinVerifyTicketResponse));

//              修改订单状态
                if (douyinVerifyTicketResponse.getData().getErrorCode() == 0) {
                    List<DouyinVerifyTicketResponse.VerifyData> verifyResults = douyinVerifyTicketResponse.getData().getVerifyResults();
                    for (DouyinVerifyTicketResponse.VerifyData verifyResult : verifyResults) {
                        if (StringUtil.isBlank(orderId) && StringUtil.isNotBlank(verifyResult.getOrderId())) {
                            orderId =verifyResult.getOrderId();
                        }

                        if (StringUtil.isNotBlank(orderId)) {

                            SlkjOrder order = slkjOrderMapper.selectSlkjOrderByThird(orderId);
                            if (order == null) {
                                log.error("抖音订单核销成功，数据库中订单匹配异常。核销信息：{}", JSON.toJSONString(verifyResults));
                                throw new ServiceException("核销成功，修改订单状态异常！");
                            }
                            order.setUpdateBy(SecurityUtils.getUserId() + "");
                            order.setUpdateTime(DateUtils.getNowDate());


                            List<SlkjOrderStatusLog> statusLogs = new ArrayList<>();
                            SlkjOrderStatusLog orderStatusLog;
                            OrderType orderType = OrderType.fromCode(order.getOrderType());
                            switch (orderType) {
                                case OT_101:
                                    orderStatusLog = new SlkjOrderStatusLog();
                                    orderStatusLog.setOrderId(order.getOrderId());
                                    orderStatusLog.setStatus(OrderBusinessStatus.REDEEMED.getCode());
                                    orderStatusLog.setChangeBy(SecurityUtils.getUserId());
                                    orderStatusLog.setChangeTime(DateUtils.getNowDate());
                                    statusLogs.add(orderStatusLog);
                                    order.setBusinessStatus(OrderBusinessStatus.REDEEMED.getCode());
                                    break;
                                case OT_102:
                                    // 已核销
                                    orderStatusLog = new SlkjOrderStatusLog();
                                    orderStatusLog.setOrderId(order.getOrderId());
                                    orderStatusLog.setStatus(OrderBusinessStatus.REDEEMED.getCode());
                                    orderStatusLog.setChangeBy(SecurityUtils.getUserId());
                                    orderStatusLog.setChangeTime(order.getUpdateTime());
                                    statusLogs.add(orderStatusLog);

                                    ThreadUtil.sleep(50);
                                    // 已完成
                                    orderStatusLog = new SlkjOrderStatusLog();
                                    orderStatusLog.setOrderId(order.getOrderId());
                                    orderStatusLog.setStatus(OrderBusinessStatus.COMPLETED.getCode());
                                    orderStatusLog.setChangeBy(SecurityUtils.getUserId());
                                    orderStatusLog.setChangeTime(DateUtils.getNowDate());
                                    statusLogs.add(orderStatusLog);
                                    order.setGoodsStatus(GoodsStatusEnum.COMPLETED.name());
                                    break;
                                default:
                                    log.error("抖音订单核销成功，数据库中订单匹配异常。核销信息：{}", JSON.toJSONString(verifyResults));
                                    throw new ServiceException("核销成功，订单录入有误，请咨询客服！");
                            }
                            log.info("更新订单状态：{}", JSON.toJSONString(order));
                            slkjOrderMapper.updateSlkjOrder(order);

                            log.info("批量插入订单状态日志：{}", JSON.toJSONString(statusLogs));
                            slkjOrderStatusLogMapper.batchInsert(statusLogs);

                            log.info("订单 [order_id={}] 核销成功！", order.getOrderId());
                            return AjaxResult.success("核销成功！", order.getOrderId());
                        } else {
                            log.error("抖音订单核销成功，数据库中订单号匹配异常：{}", JSON.toJSONString(verifyResults));
                            throw new ServiceException("抖音订单核销成功，数据库中订单号匹配异常："+JSON.toJSONString(verifyResults));
                        }
                    }
                } else {
                    log.error("验卷失败： " + JSON.toJSONString(douyinVerifyTicketResponse));
                    throw new ServiceException("验卷失败，请联系客服");
                }

            } else {

                log.error("验券前置条件有误，验卷失败失败： " + JSON.toJSONString(douyinPreVerifyTicketResponse));
                throw new ServiceException("验券前置条件有误，验卷失败,"+douyinPreVerifyTicketResponse.getData().getDescription());
            }

        } catch (IOException e) {
            e.printStackTrace();
            log.error("核销异常，请咨询客服");
            throw new ServiceException("核销异常，请咨询客服！");
        }
        return AjaxResult.success("核销成功！");
    }


    // 获取重定向后的 URL
    public static String getRedirectedUrl(String shortUrl) throws IOException {
        HttpURLConnection connection = (HttpURLConnection) new URL(shortUrl).openConnection();
        connection.setInstanceFollowRedirects(false); // 设为 false 以手动处理重定向
        connection.connect();

        // 检查是否存在重定向
        int statusCode = connection.getResponseCode();
        if (statusCode == HttpURLConnection.HTTP_MOVED_TEMP || statusCode == HttpURLConnection.HTTP_MOVED_PERM) {
            String redirectedUrl = connection.getHeaderField("Location");
            return redirectedUrl; // 返回重定向后的 URL
        }

        throw new IOException("未找到重定向 URL");
    }

    // 从 URL 中提取 object_id 参数
    public static String extractObjectId(String url) {
        Pattern pattern = Pattern.compile("object_id=([^&]+)");
        Matcher matcher = pattern.matcher(url);
        if (matcher.find()) {
            return matcher.group(1); // 返回 object_id 的值
        }
        return null;
    }
}
